﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections;
using System.Globalization;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;

namespace VSM
{
    public class GeneralFunctions
    {
        private static MasterData MD;
        private static DataSet ds;
        private CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentCulture;
        private ArrayList fileLines;
        private string[] ChuSo = new string[10] { " không", " một", " hai", " ba", " bốn", " năm", " sáu", " bẩy", " tám", " chín" };
        private string[] Tien = new string[6] { "", " nghìn", " triệu", " tỷ", " nghìn tỷ", " triệu tỷ" };
        
        public GeneralFunctions()
        {

        }

        public GeneralFunctions(string asUserName)
        {
            MD = new MasterData();
            //ds = MD.GetDisplaySetting(asUserName);
           // ds = MD.GetDisplaySetting("ELECTRA");
        }

        public GeneralFunctions(string dbType, string ID_Dealer)
        {
            MD = new MasterData();
            ds = MD.GetDisplaySetting(dbType, ID_Dealer);
            // ds = MD.GetDisplaySetting("ELECTRA");
        }

        #region Properties
        public string DateFormatString
        {
            get { return "MM/dd/yyyy"; }
        }
        public string DecSep
        {
            get { return (ds.Tables[0].Rows[0]["DecSep"] == null ? "." : ds.Tables[0].Rows[0]["DecSep"].ToString()); }
        }

        public string ThousSep
        {
            get { return (ds.Tables[0].Rows[0]["ThousSep"] == null ? "," : ds.Tables[0].Rows[0]["ThousSep"].ToString()); }
        }

        public int SumDec
        {
            get { return (ds.Tables[0].Rows[0]["SumDec"] == null ? 0 : int.Parse(ds.Tables[0].Rows[0]["SumDec"].ToString())); }
        }

        public int QtyDec
        {
            get { return (ds.Tables[0].Rows[0]["QtyDec"] == null ? 0 : int.Parse(ds.Tables[0].Rows[0]["QtyDec"].ToString())); }
        }

        public int PriceDec
        {
            get { return (ds.Tables[0].Rows[0]["PriceDec"] == null ? 0 : int.Parse(ds.Tables[0].Rows[0]["PriceDec"].ToString())); }
        }

        public int PercentDec
        {
            get { return (ds.Tables[0].Rows[0]["PercentDec"] == null ? 2 : int.Parse(ds.Tables[0].Rows[0]["PercentDec"].ToString())); }
        }

        public int RateDec
        {
            get { return (ds.Tables[0].Rows[0]["RateDec"] == null ? 2 : int.Parse(ds.Tables[0].Rows[0]["RateDec"].ToString())); }
        }

        public ArrayList FileLines
        {
            get { return fileLines; }
            set { fileLines = value; }
        }
        #endregion

        
        public string BuildKeepColumnStr(DataTable dt)
        {
            string str = "";
            foreach (DataColumn column in dt.Columns)
            {
                str = str + column.ColumnName + ";";
            }
            return str;
        }
        public DataTable ConvertDataTable_RemoveCols(DataTable dt, string KeepColumns)
        {
            DataTable dt1 = dt;
            Array arr = KeepColumns.Split(';');
            CultureInfo ivC = new System.Globalization.CultureInfo("es-US");
            string strcolumnremove = "";
            foreach (var column in dt1.Columns.Cast<DataColumn>().ToArray())
            {
                if (KeepColumns!="")
                {
                    if (Array.IndexOf(arr, column.ColumnName) < 0)
                    {//-------neu ko nam trong danh sach column giu lai, thi delete-----------------
                        dt1.Columns.Remove(column);
                    }
                }
                if (Array.IndexOf(arr, column.ColumnName) >= 0 || KeepColumns=="")
                {
                    if (column.DataType != typeof(string)) //chuyen doi tat ca kieu du lieu, ngoai tru kieu string
                    {
                        strcolumnremove = strcolumnremove + column.ColumnName + ";";
                        dt1.Columns.Add(column.ColumnName + "_1xxx", typeof(string)); //them cot
                        
                        foreach (DataRow row in dt1.Rows)
                        {
                            if (column.DataType == typeof(DateTime) & row[column].ToString()!="")
                            {
                                DateTime d = Convert.ToDateTime(row[column].ToString(), ivC);
                                row[column.ColumnName + "_1xxx"] = String.Format("{0:yyyyMMdd}", d);
                            }
                            else
                                row[column.ColumnName + "_1xxx"] = row[column].ToString();
                        }
                    }
                }
            }
            //Xoa cac cot co kieu du lieu khac string, doi ten cac cot du lieu moi.
            if (strcolumnremove != "")
            {
                Array arr1= strcolumnremove.Split(';');
                for (int i = 0; i < arr1.Length; i++)
                {
                    if (arr1.GetValue(i).ToString() != "")
                    {
                        dt1.Columns.Remove(arr1.GetValue(i).ToString());
                        dt1.Columns[arr1.GetValue(i).ToString() + "_1xxx"].ColumnName = arr1.GetValue(i).ToString();
                    }
                }
            }
            return dt1;
        }

        #region Transfer from Obj to Double
        public Double Object2Double(Object Obj)
        {
            double result = 0.0;
            try
            {
                if (Obj != null)
                {
                    if (Obj.ToString().IndexOf(ci.NumberFormat.NumberGroupSeparator) > 0)
                        Obj = Obj.ToString().Replace(ci.NumberFormat.NumberGroupSeparator, ci.NumberFormat.NumberDecimalSeparator);
                    result = Double.Parse(Obj.ToString(), ci);
                }
            }
            catch 
            {
                result = 0.0;
            }
            return result;        
        }
        #endregion

        #region Transfer from Obj & Display Setting Name
        public Double Object2Double(Object Obj, string attName)
        {
            double result=0.0;
            try
            {
                if (Obj != null)
                {
                    if (Obj.ToString().IndexOf(ci.NumberFormat.NumberGroupSeparator) > 0)
                        Obj = Obj.ToString().Replace(ci.NumberFormat.NumberGroupSeparator, ci.NumberFormat.NumberDecimalSeparator);
                    return result = Math.Round(Double.Parse(Obj.ToString(), ci), GetNumDecimals(attName));
                }
            }
            catch 
            {
                result = 0.0;
            }
            return 0.0;
        }
        #endregion

        #region Get Number Decimal of Display Setting Name
        public int GetNumDecimals(string attName)
        {
            switch (attName)
            {
                case "SumDec":
                    return SumDec;
                case "PriceDec":
                    return PriceDec;
                case "QtyDec":
                    return QtyDec;
                case "PercentDec":
                    return PercentDec;
                case "RateDec":
                    return RateDec;
                default: return 0;
            }
        }
        #endregion

        #region FormatNumeric
        public string FormatNumeric(string strValor, string asNumDecimales)
        {
            if (strValor == "") return "0";

            int intNumDecimales = GetNumDecimals(asNumDecimales);

            string NumberGroupSeparator = this.ThousSep, NegativeSign = "-", NegativeSignOrg = "";
            string PercentDecimalSeparator = this.DecSep, NumberDecimalSeparator = this.DecSep;

            strValor = (Math.Round(Double.Parse(strValor), intNumDecimales)).ToString();

            string strAux = null;
            string strComas = string.Empty;
            string strPuntos = null;

            if (strValor.Length == 0) return "";
            strValor = strValor.Replace(NumberGroupSeparator, NumberDecimalSeparator);
            if (strValor.Contains(NumberDecimalSeparator))
            {
                strAux = strValor.Substring(0, strValor.LastIndexOf(NumberDecimalSeparator));
                strComas = strValor.Substring(strValor.LastIndexOf(NumberDecimalSeparator) + 1);
            }
            else
            {
                strAux = strValor;
            }

            if (strAux.Substring(0, 1) == NegativeSign)
            {
                strAux = strAux.Substring(1);
                NegativeSignOrg = "-";
            }

            strPuntos = strAux;
            strAux = "";
            while (strPuntos.Length > 3)
            {
                strAux = NumberGroupSeparator + strPuntos.Substring(strPuntos.Length - 3, 3) + strAux;
                strPuntos = strPuntos.Substring(0, strPuntos.Length - 3);
            }
            if (intNumDecimales > 0)
            {
                if (strValor.Contains(PercentDecimalSeparator))
                {
                    strComas = PercentDecimalSeparator + strValor.Substring(strValor.LastIndexOf(PercentDecimalSeparator) + 1);
                    if (strComas.Length > intNumDecimales)
                    {
                        strComas = strComas.Substring(0, intNumDecimales + 1);
                    }

                }
            }
            strAux = NegativeSignOrg + strPuntos + strAux + strComas;

            return strAux;
        }
        #endregion

        #region Reset format numeric functions
        public string ResetFormatNumeric(string strValor)
        {
            return strValor.Replace(ThousSep, "");
        }

        public DataTable ResetFormatNumeric(DataTable dt, Array arr)
        {
            foreach (DataRow row in dt.Rows)
            {
                foreach(string ls in arr)
                {
                    row[ls] = ResetFormatNumeric(row[ls].ToString());
                }
            }
            return dt;
        }
        #endregion


        public DataTable RunQuery(String Query)
        {
            DataTable results = new DataTable();
            using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["dbconnection"].ToString()))
            {
                SqlCommand command = new SqlCommand(Query, conn);
                SqlDataAdapter adapter = new SqlDataAdapter(command);
                conn.Open();
                adapter.Fill(results);
            }
            return results;
        }

        public static string UrlFullEncode(string strUrl)
        {
            if (strUrl == null)
                return "";
            strUrl = System.Web.HttpUtility.UrlEncode(strUrl);
            return strUrl.Replace("'", _strApostropheEncoding);
        }
        private const string _strApostropheEncoding = "%27";

        public int ObjectUpdate(string sp_Name, ArrayList pVarName, ArrayList pValList)
        {
            SqlConnection myConn = null;
            try
            {
                String conStr = ConfigurationManager.ConnectionStrings["LocalSqlServer"].ToString();
                myConn = new SqlConnection(conStr);
                myConn.Open();
                SqlCommand myCommand = new SqlCommand(sp_Name, myConn);
                myCommand.CommandType = CommandType.StoredProcedure;
                for (int i = 0; i <= pVarName.Count - 1; i++)
                {
                    myCommand.Parameters.AddWithValue(pVarName[i].ToString(), pValList[i]);
                }

                SqlParameter myParameter = new SqlParameter("@Result", SqlDbType.Int);
                myParameter.Direction = ParameterDirection.Output;
                myCommand.Parameters.Add(myParameter);
                myCommand.ExecuteNonQuery();
                myConn.Close();
                int re = 0;
                re = Convert.ToInt32(myCommand.Parameters[myCommand.Parameters.Count - 1].Value);
                return re;

            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if ((myConn != null))
                {
                    myConn.Close();
                }
            }

        }

        public DataTable ObjectSelect(string sp_Name, ArrayList pVarName, ArrayList pValList)
        {
            SqlConnection myConn = null;
            try
            {
                String conStr = ConfigurationManager.ConnectionStrings["LocalSqlServer"].ToString();
                myConn = new SqlConnection(conStr);
                myConn.Open();
                SqlCommand myCommand = new SqlCommand(sp_Name, myConn);
                myCommand.CommandType = CommandType.StoredProcedure;
                for (int i = 0; i <= pVarName.Count - 1; i++)
                {
                    myCommand.Parameters.AddWithValue(pVarName[i].ToString(), pValList[i]);
                }
                SqlDataAdapter da = new SqlDataAdapter();
                da.SelectCommand = myCommand;
                DataSet ds = new DataSet();
                da.Fill(ds);
                //myCommand.ExecuteReader()
                myConn.Close();

                return ds.Tables[0];

            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if ((myConn != null))
                {
                    myConn.Close();
                }
            }

        }

        public void BindDataSaleMan(string dbType, string ID_Dealer, DropDownList ddlControl, string slpCode)
        {
            DataSet dsSaleMan = MD.GetSalesMan(dbType, ID_Dealer);
            if (dsSaleMan != null && dsSaleMan.Tables.Count > 0)
            {
                if (ddlControl.Items.Count > 0) ddlControl.Items.Clear();
                ddlControl.DataSource = dsSaleMan.Tables[0];
                ddlControl.DataValueField = "SlpCode";
                ddlControl.DataTextField = "SlpName";
                ddlControl.DataBind();
                if (ddlControl.Items.Count > 0) ddlControl.SelectedValue = slpCode;
            }  
        }

        public DataTable GetModelList(string dbType)
        {
            DataSet dsModel = MD.GetModelList(dbType);
            if (dsModel != null && dsModel.Tables.Count > 0) return dsModel.Tables[0];
            return null;
        }

        public DataTable GetProductByModel(string dbType, string lsModelCode)
        {
            DataSet dsProduct = MD.GetProductByModel(dbType, lsModelCode);
            if (dsProduct != null && dsProduct.Tables.Count > 0) return dsProduct.Tables[0];
            return null;
        }

        public DataTable GetColorList(string dbType)
        {
            DataSet dsColor = MD.GetColorList(dbType);
            if (dsColor != null && dsColor.Tables.Count > 0) return dsColor.Tables[0];
            return null;
        }

        public DataTable GetFreightList(string dbType)
        {
            DataSet dsFreightList = MD.GetFreightList(dbType);
            if (dsFreightList != null && dsFreightList.Tables.Count > 0) return dsFreightList.Tables[0];
            return null;
        }

        public DataTable GetItem(string dbType, string ID_Dealer, string lsModel, string lsProduct, string lsColor)
        {
            DataSet dsItem = MD.GetItemsByModelProductColor(dbType, ID_Dealer, lsModel, lsProduct, lsColor);
            if (dsItem != null && dsItem.Tables.Count > 0) return dsItem.Tables[0];
            return null;
        }

        public string GetStockOnHand(string dbType, string ID_Dealer, string Whs, string ItemCode)
        {
            DataSet ds = MD.GetItemsByItemCodeList(dbType, ID_Dealer, " '" + ItemCode + "' ");
            if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count == 1) return ds.Tables[0].Rows[0]["OnHand"].ToString();

            return "0";
        }

        public string GetItemGroupByCode(string dbType, string ID_Dealer, string ItemCode)
        {
            return MD.GetItemGroupByCode(dbType, ID_Dealer, ItemCode, "ItmsGrpCod");  
        }

        public string GetSingleValue(string dbType, string sqlCommand, string keyName)
        {
            return MD.GetSingleValue(dbType, sqlCommand, keyName);
        }

        public DataTable GetMasterListBySqlCommand(string dbType, string sqlCommand)
        {
            return MD.GetMasterListBySqlCommand(dbType, sqlCommand).Tables[0];
        }

        public DataTable GetTblRDR1(string dbType, string ID_Dealer, string DocEntry, string TableLineName)
        {
            DataSet dsTblRDR1 = MD.GetTblRDR1(dbType, ID_Dealer, DocEntry, TableLineName);
            if (dsTblRDR1 != null && dsTblRDR1.Tables.Count > 0) return dsTblRDR1.Tables[0];
            return null;
        }

        public DataTable GetCustRemainAmt(string dbType, string ID_Dealer, string CardCode)
        {
            DataSet dsTblRDR1 = MD.GetCustRemainAmt(dbType, ID_Dealer, CardCode);
            if (dsTblRDR1 != null && dsTblRDR1.Tables.Count > 0) return dsTblRDR1.Tables[0];
            return null;
        }

        public DataTable GetTblRDR1RemainAmnt(string dbType, string ID_Dealer, string NumAtCard)
        {
            DataSet dsTblRDR1 = MD.GetTblRDR1RemainAmnt(dbType, ID_Dealer, NumAtCard);
            if (dsTblRDR1 != null && dsTblRDR1.Tables.Count > 0) return dsTblRDR1.Tables[0];
            return null;
        }

        public DataTable GetDealers(string dbType, string ID_Dealer, string GrpCode)
        {
            DataSet dsDealers = MD.GetCustomers(dbType, ID_Dealer, GrpCode);
            if (dsDealers != null && dsDealers.Tables.Count > 0) return dsDealers.Tables[0];
            return null;
        }

        public DataTable GetCustomerDetails(string dbType, string CardCode, string Type)
        {
            DataSet dsCRD10 = MD.GetCustomerDetails(dbType, CardCode, Type);
            if (dsCRD10 != null && dsCRD10.Tables.Count > 0) return dsCRD10.Tables[0];
            return null;
        }

        public DataTable GetWarehouseByDealerDepartment(string dbType, string ID_Dealer, string Department)
        {
            DataSet dsWhs = MD.GetWarehouseByDealerDepartment(dbType, ID_Dealer, Department);
            if (dsWhs != null && dsWhs.Tables.Count > 0) return dsWhs.Tables[0];
            return null;
        }

        public DataTable GetVatGroupByCategory(string dbType, string Category)
        {
            DataSet dsVatGroup = MD.GetVatGroupByCategory(dbType, Category);
            if (dsVatGroup != null && dsVatGroup.Tables.Count > 0) return dsVatGroup.Tables[0];
            return null;
        }

        public DataTable GetItemsAdvancePayment(string dbType, string DocEntry)
        {
            DataSet dsItems = MD.GetItemsAdvancePayment(dbType, DocEntry);
            if (dsItems != null && dsItems.Tables.Count > 0) return dsItems.Tables[0];
            return null;
        }

        public DataTable GetSummaryOfInventory(string storeName, DataSet ParamArrays, string dbType)
        {
            DataSet dsSummaryOfInventoryCard = MD.GetReports_DS(storeName, ParamArrays, dbType);
            if (dsSummaryOfInventoryCard != null && dsSummaryOfInventoryCard.Tables.Count > 0) return dsSummaryOfInventoryCard.Tables[0];
            return null;
        }

        public DataTable GetVSMPlanQty(string storeName, DataSet ParamArrays, string dbType)
        {
            DataSet dsVSMPlanQty = MD.GetReports_DS(storeName, ParamArrays, dbType);
            if (dsVSMPlanQty != null && dsVSMPlanQty.Tables.Count > 0) return dsVSMPlanQty.Tables[0];
            return null;
        }

        public DataSet GetCustomerProfiles(string dbType, string ID_Dealer, string GroupCode)
        { 
            string sqlCommand = string.Empty;
            if (dbType.Equals(Utils.AppConstants.VSM))
                sqlCommand = "select CardCode, CardName, Address, E_Mail, case when CardType = 'C' then 'Customer' else 'Lead' end AS CardType, "
                    + " U_ContactPerson, U_Remain, convert(varchar(10), CreateDate, 103) As CreateDate, convert(varchar(10), UpdateDate, 103) As UpdateDate " 
                    + " from OCRD where CardType in ('L', 'C') and GroupCode in " + GroupCode;
            else
                sqlCommand = "select CardCode, CardName, Address, E_Mail, case when CardType = 'C' then 'Customer' else 'Lead' end AS CardType, "
                        + " U_ContactPerson, U_Remain, convert(varchar(10), CreateDate, 103) As CreateDate, convert(varchar(10), UpdateDate, 103) As UpdateDate "
                    + "from OCRD where CardType in ('L', 'C') and ( GroupCode in (103) or  GroupCode in " + GroupCode + " )";

            if (!string.IsNullOrEmpty(ID_Dealer) && !ID_Dealer.Equals(Utils.AppConstants.VSM))
                sqlCommand += " and ( U_DealerCode = '" + ID_Dealer + "' or CardCode = '" + ID_Dealer + "' )";
            
            // Only get Customer Active
            sqlCommand += " and CardCode not in (select CardCode from OCRD where ValidFor = 'N' and frozenFor = 'Y') ";

            return MD.GetMasterListBySqlCommand(dbType, sqlCommand);
        }

        public string ReadFile(Stream FileStreamObj)
        {
            try
            {
                using (StreamReader Reader = new StreamReader(FileStreamObj, System.Text.UTF8Encoding.UTF8))
                {
                    if (FileLines == null) FileLines = new ArrayList();
                    else FileLines.Clear();
                    string line;
                    // Read and display lines from the file until the end of the file is reached.
                    while ((line = Reader.ReadLine()) != null)
                    {
                        FileLines.Add(line);
                    }
                    Reader.Close();
                }
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
            return string.Empty;
        }

        public string Amount2Words(long SoTien, string strTail)
        {
            int lan, i;
            long so;
            string KetQua = string.Empty, tmp = string.Empty;
            int[] ViTri = new int[6];
            if (SoTien < 0) return "Số tiền âm !";
            if (SoTien == 0) return "Không đồng !";
            if (SoTien > 0)
            {
                so = SoTien;
            }
            else
            {
                so = -SoTien;
            }
            // Check big amount
            if (SoTien > 8999999999999999)
            {
                SoTien = 0;
                return string.Empty;
            }
            ViTri[5] = (int)(so / 1000000000000000);
            so = so - long.Parse(ViTri[5].ToString()) * 1000000000000000;
            ViTri[4] = (int)(so / 1000000000000);
            so = so - long.Parse(ViTri[4].ToString()) * +1000000000000;
            ViTri[3] = (int)(so / 1000000000);
            so = so - long.Parse(ViTri[3].ToString()) * 1000000000;
            ViTri[2] = (int)(so / 1000000);
            ViTri[1] = (int)((so % 1000000) / 1000);
            ViTri[0] = (int)(so % 1000);
            if (ViTri[5] > 0)
            {
                lan = 5;
            }
            else if (ViTri[4] > 0)
            {
                lan = 4;
            }
            else if (ViTri[3] > 0)
            {
                lan = 3;
            }
            else if (ViTri[2] > 0)
            {
                lan = 2;
            }
            else if (ViTri[1] > 0)
            {
                lan = 1;
            }
            else
            {
                lan = 0;
            }
            for (i = lan; i >= 0; i--)
            {
                tmp = DocSo3ChuSo(ViTri[i]);
                KetQua += tmp;
                if (ViTri[i] != 0) KetQua += Tien[i];
                if ((i > 0) && (!string.IsNullOrEmpty(tmp))) KetQua += ",";//&& (!string.IsNullOrEmpty(tmp))
            }
            if (KetQua.Substring(KetQua.Length - 1, 1) == ",") KetQua = KetQua.Substring(0, KetQua.Length - 1);
            KetQua = KetQua.Trim() + strTail;
            return KetQua.Substring(0, 1).ToUpper() + KetQua.Substring(1);
        }

        // Hàm đọc số có 3 chữ số
        private string DocSo3ChuSo(int baso)
        {
            int tram, chuc, donvi;
            string KetQua = "";
            tram = (int)(baso / 100);
            chuc = (int)((baso % 100) / 10);
            donvi = baso % 10;
            if ((tram == 0) && (chuc == 0) && (donvi == 0)) return "";
            if (tram != 0)
            {
                KetQua += ChuSo[tram] + " trăm";
                if ((chuc == 0) && (donvi != 0)) KetQua += " linh";
            }
            if ((chuc != 0) && (chuc != 1))
            {
                KetQua += ChuSo[chuc] + " mươi";
                if ((chuc == 0) && (donvi != 0)) KetQua = KetQua + " linh";
            }
            if (chuc == 1) KetQua += " mười";
            switch (donvi)
            {
                case 1:
                    if ((chuc != 0) && (chuc != 1))
                    {
                        KetQua += " mốt";
                    }
                    else
                    {
                        KetQua += ChuSo[donvi];
                    }
                    break;
                case 5:
                    if (chuc == 0)
                    {
                        KetQua += ChuSo[donvi];
                    }
                    else
                    {
                        KetQua += " lăm";
                    }
                    break;
                default:
                    if (donvi != 0)
                    {
                        KetQua += ChuSo[donvi];
                    }
                    break;
            }
            return KetQua;
        }

    }
}